home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 8
/
Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso
/
Aminet
/
util
/
cdity
/
Yak210src.lha
/
Yak_2.10_Src
/
WBStartup
/
Hotkey_actions.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-17
|
29KB
|
1,342 lines
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/commodities.h>
#include <proto/locale.h>
#include <proto/reqtools.h>
#include <clib/alib_protos.h>
#include <exec/types.h>
#include <exec/tasks.h>
#include <dos/dostags.h>
#include <dos/datetime.h>
#include <intuition/intuitionbase.h>
#include <libraries/locale.h>
#include <libraries/reqtools.h>
#include <string.h>
#include "code.h"
#include "yak.h"
#include "hotkey_types.h"
#include "Handlers.h"
#include "Settings.h"
#include "Requesters.h"
#include "GetScreenBox.h"
#include "GetPubScreen.h"
#include "Arexx.h"
#include "LastActiveWindow.h"
#ifndef USE_WB2CLI
# include "wbpath.h"
#endif
#define CATCOMP_NUMBERS
#include "yak_locale_strings.h"
IMPORT BOOL ShowYakInterface (VOID);
static void __regargs YakMoveScreen(struct Screen *scr, UWORD flags);
static void __regargs EnlargeWindow(struct Window *win, UWORD flags);
static void ChangeScreen(YakOption *opt);
static struct Window *SelectWindow(YakOption *opt);
static struct Screen *SelectScreen(YakOption *opt);
static SAVEDS ASM void putcharfunc( REG(a0) struct Hook *h,
REG(a2) void *object,
REG(a1) char c);
static struct InputEvent *FlipIEvents(struct InputEvent *);
static int AddToStream(char *str, UBYTE delay);
static struct Window * FindWBWindow(void);
static SAVEDS void DoPalette(void);
static int palette_count;
static LONG beginCommand(char *command, LONG stack, LONG Priority);
static struct Window *ActiveWindow(void);
static struct Screen *ActiveScreen(void);
extern struct WBStartup *WBMsg;
/* okay to quit? (not so if palettes open) */
int
OkayToExit()
{
return (palette_count == 0);
}
/* hook-function for inserting chars into input-stream */
static SAVEDS ASM void
putcharfunc(REG(a0) struct Hook *h,
REG(a2) void *object,
REG(a1) char c)
{
struct InputEvent ev;
if (c) /* stop at null-terminator */
{
ev.ie_NextEvent = NULL;
InvertKeyMap(c, &ev, NULL);
AddIEvents(&ev);
}
}
/* and its associated structure */
static struct Hook putcharhook = {
{NULL, NULL},
(APTR)putcharfunc,
NULL,
NULL
};
/* given a list of input events, reverse their order */
/* NB: the list BETTER terminate... */
static struct InputEvent *
FlipIEvents(struct InputEvent *ie)
{
struct InputEvent *oldtail, *newtail = NULL;
while (ie)
{
/* remove head, set next event */
oldtail = ie->ie_NextEvent; /* this will be prev event */
ie->ie_NextEvent = newtail; /* add to head */
newtail = ie;
ie = oldtail; /* what's left */
}
return newtail;
}
/* adds a string to the input-stream */
static int
AddToStream(char *str, UBYTE delay)
{
struct InputEvent *ie;
if (ie = InvertString(str, NULL))
{
ie = FlipIEvents(ie);
if (delay>0)
{
struct InputEvent *next;
while (ie)
{
next = ie->ie_NextEvent;
ie->ie_NextEvent = NULL;
AddIEvents(ie);
FreeIEvents(ie);
Delay(delay);
ie = next;
}
}
else
{
AddIEvents(ie);
FreeIEvents(ie);
}
return TRUE;
}
return FALSE;
}
/* find (a) Workbench window */
static struct Window *
FindWBWindow()
{
struct Screen *s = LockPubScreen("Workbench");
if (s)
{
struct Window *w = s->FirstWindow;
WBenchToFront();
Forbid();
for (; w; w = w->NextWindow)
if (w->Flags & WFLG_WBENCHWINDOW)
break;
Permit();
UnlockPubScreen(NULL, s);
return w;
}
return NULL;
}
/* bring a palette up on screen */
/* CreateNewProc this function... */
static SAVEDS void
DoPalette()
{
struct ReqToolsBase *ReqToolsBase;
struct Screen *mousescr;
struct Window *win;
STRPTR title=getString(Palette_Title);
LONG tags[3];
if (ReqToolsBase = (void *)OpenLibrary("reqtools.library", 0L))
{
mousescr = ReqToolsBase->IntuitionBase->FirstScreen;
win=mousescr->FirstWindow;
while (win)
{
if ((win->Title) && !strcmp(title, win->Title))
{
WindowToFront(win);
ActivateWindow(win);
return;
}
win=win->NextWindow;
}
palette_count++;
tags[0] = RT_Screen;
tags[1] = (LONG)mousescr;
tags[2] = TAG_DONE;
(void) rtPaletteRequestA(title, NULL, (struct TagItem *)tags);
CloseLibrary((struct Library *)ReqToolsBase);
}
palette_count--;
}
/*
* Asynchronous external command started with its own autocon Input/Output
* Result will only reflect whether System() call itself succeeded.
* If System() call fails, result will be -1L; -2L for window failure.
* We are using -2L as result if our Open of CON: fails
*/
#define AUTOCON "CON:0/25/640/150/Yak Command/AUTO/CLOSE/WAIT/ALT0/25/80/50"
static LONG
beginCommand(char *command, LONG Stack, LONG Priority)
{
static ULONG stags[] = {
SYS_Input, NULL,
SYS_Output, NULL,
SYS_Asynch, TRUE,
SYS_UserShell, TRUE,
NP_Priority, 0L,
NP_StackSize, 4000L,
#ifndef USE_WB2CLI
NP_Path, 0L,
#endif
TAG_DONE
};
BPTR file;
char *filename;
#ifdef NOTDEF /* will this screw up sometimes? */
char *t;
int inquote = FALSE, usecon = TRUE;
/* determine (simple-mindedly) whether there's redirection */
for (t = command; *t; t++)
{
if (*t == '\"')
if (t <= command || t[-1] != '*')
inquote ^= 1;
if (!inquote)
if (*t == '>')
{
usecon = FALSE;
break;
}
}
filename = usecon ? AUTOCON : "NIL:";
#else
filename = AUTOCON;
#endif
if (file = Open(filename, MODE_OLDFILE))
{
stags[1] = (ULONG)file;
stags[9] = Priority;
if (Stack>0)
{
stags[11] = Stack;
}
#ifndef USE_WB2CLI
if (WBMsg)
{
stags[13] = (ULONG) CloneWorkbenchPath(WBMsg);
}
#endif
return(SystemTagList(command, (struct TagItem *)stags));
}
else return(-2);
}
/* execute a command */
void
act_ExecuteCommand(YakHotKey *yhk)
{
LONG rc;
if (yhk->yhk_Option[1].ArgStr[0])
{
ChangeScreen(&yhk->yhk_Option[0]);
if (yhk->yhk_Option[1].Flags & HKO_CLI_COMMAND)
{
rc = beginCommand(yhk->yhk_Option[1].ArgStr[0],
yhk->yhk_Option[1].ArgNum[0],
yhk->yhk_Option[1].ArgNum[1]);
}
else
{
rc = SendARexxCommand(yhk->yhk_Option[1].ArgStr[1], yhk->yhk_Option[1].ArgStr[0]);
}
if (rc != 0)
PostError("%s\n\"%s\"",
getString(Couldnt_execute_command_ERR),
yhk->yhk_Option[1].ArgStr[0]);
}
else
PostError("%s\"%s\".",
getString(No_cmd_specified_for_hotkey_ERR),
yhk->yhk_KeyDef);
}
void
act_CloseWindow(YakHotKey *yhk)
{
/* CloseEvent is declared as static to save some bytes and speed up code */
static struct InputEvent CloseEvent = { NULL, IECLASS_CLOSEWINDOW, 0, 0, 0, 0 };
struct Window *window;
struct Window *CurrentWindow = NULL;
CurrentWindow = ActiveWindow();
if (window = SelectWindow(&yhk->yhk_Option[0]))
{
if (window && (window->Flags & CLOSEGADGET))
{
ActivateWindow(window);
AddIEvents(&CloseEvent);
do
{
Delay(1);
} while (window == ActiveWindow());
if (CurrentWindow && (window != CurrentWindow))
{
ActivateWindow(CurrentWindow);
}
else
{
if (autopoint)
{
ActivateMouseWindow (KEY);
}
}
}
}
}
/*
* This function simulates Intuition mutal exclusion for menu items.
*/
static __regargs void
UnCheckExcludedItems(UWORD menu,
UWORD item,
UWORD sub,
ULONG MutualExclude,
struct Window *window)
{
struct MenuItem *menuitem;
UWORD menuNumber;
UBYTE i=0;
while (MutualExclude > 0)
{
if (MutualExclude & 1)
{
/* Item to exclude */
if (sub == NOSUB)
{
item = i;
}
else
{
sub = i;
}
menuNumber = FULLMENUNUM( menu, item, sub );
menuitem = ItemAddress(window->MenuStrip, menuNumber);
if ((menuitem) && /* item must exist */
(menuitem->Flags & ITEMENABLED) && /* item must be enabled */
(menuitem->Flags & CHECKED)) /* item must be checked */
{
menuitem->Flags &= ~CHECKED;
}
}
MutualExclude = MutualExclude >> 1;
i++;
}
}
void
act_MenuShortcut(YakHotKey *yhk)
{
/* MenuEvent is declared as static to save some bytes and speed up code */
static struct InputEvent MenuEvent = { NULL, IECLASS_MENULIST, 0, 0, IEQUALIFIER_LEFTBUTTON, 0 };
struct Window *window;
struct MenuItem *menuitem;
UWORD menuNumber, menu, item, sub;
window = ActiveWindow();
menu = (UWORD) yhk->yhk_Option[0].ArgNum[0];
item = (UWORD) yhk->yhk_Option[0].ArgNum[1];
if (yhk->yhk_Option[0].Flags & HKO_SUBITEM)
{
sub = (UWORD) yhk->yhk_Option[0].ArgNum[2];
}
else
{
/* no subitem specified */
sub = NOSUB;
}
if (window && (window->MenuStrip))
{
menuNumber = FULLMENUNUM( menu, item, sub );
menuitem = ItemAddress(window->MenuStrip, menuNumber);
if ((menuitem) && /* item must exist */
(menuitem->Flags & ITEMENABLED)) /* item must be enabled */
{
/* We don't want multi selection */
menuitem->NextSelect = MENUNULL;
/* Take care of checkit items */
if (menuitem->Flags & CHECKIT)
{
if (menuitem->Flags & MENUTOGGLE)
{
if (menuitem->Flags & CHECKED)
{
/* If it's already checked, uncheck it */
menuitem->Flags &= ~CHECKED;
}
else
{
/* If it's unchecked, check it */
menuitem->Flags |= CHECKED;
}
}
else
{
/* Mutual Exclude */
if ((menuitem->Flags & CHECKED) == FALSE)
{
/* check it */
menuitem->Flags |= CHECKED;
/* and then take care of excluded items */
UnCheckExcludedItems(menu, item, sub, menuitem->MutualExclude, window);
}
}
}
/* Send our event */
MenuEvent.ie_Code = menuNumber;
MenuEvent.ie_EventAddress = window;
AddIEvents(&MenuEvent);
}
}
}
void
act_ZipWindow(YakHotKey *yhk)
{
struct Window *window;
ULONG lock;
lock = LockIBase(0);
if (window = SelectWindow(&yhk->yhk_Option[0]))
{
if (window->Flags & WFLG_HASZOOM)
ZipWindow(window);
}
UnlockIBase(lock);
}
void
act_ShrinkWindow(YakHotKey *yhk)
{
struct Window *window;
ULONG lock;
lock = LockIBase(0);
if (window = SelectWindow(&yhk->yhk_Option[0]))
{
if (window->Flags & WFLG_SIZEGADGET)
ChangeWindowBox(window,
window->LeftEdge,
window->TopEdge,
window->MinWidth,
window->MinHeight);
}
UnlockIBase(lock);
}
void
act_ExpandWindow(YakHotKey *yhk)
{
struct Window *win;
ULONG lock;
lock = LockIBase(0);
if (win = SelectWindow(&yhk->yhk_Option[0]))
{
if (win->Flags & WFLG_SIZEGADGET)
{
EnlargeWindow(win, yhk->yhk_Option[1].Flags);
}
}
UnlockIBase(lock);
}
void
act_MoveWindow(YakHotKey *yhk)
{
struct Window *win;
WORD top, left,
width, height;
ULONG lock;
struct IBox box;
struct Screen *s;
lock = LockIBase(0);
if (win=SelectWindow(&yhk->yhk_Option[0]))
{
if (win->Flags & WFLG_DRAGBAR)
{
top = win->TopEdge;
left = win->LeftEdge;
width = win->Width;
height = win->Height;
s = win->WScreen;
GetScreenBox(s, &box, (yhk->yhk_Option[1].Flags & HKO_MOVE_VISIBLE_BAR));
if (yhk->yhk_Option[1].Flags & HKO_MOVE_LEFT)
left = box.Left;
if (yhk->yhk_Option[1].Flags & HKO_MOVE_HORIZONTAL_CENTER)
left = box.Left + (box.Width-width)>>1;
if (yhk->yhk_Option[1].Flags & HKO_MOVE_RIGHT)
left = box.Left + box.Width - width;
if (yhk->yhk_Option[1].Flags & HKO_MOVE_TOP)
top = box.Top;
if (yhk->yhk_Option[1].Flags & HKO_MOVE_VERTICAL_CENTER)
top = box.Top + (box.Height-height)/2;
if (yhk->yhk_Option[1].Flags & HKO_MOVE_BOTTOM)
top = box.Top + box.Height - height;
if (win->LeftEdge != left || win->TopEdge != top)
ChangeWindowBox(win,
left,
top,
width,
height);
}
}
UnlockIBase(lock);
}
/*
* This function tells if a window has to be cycled according to
* the cycling options
*/
__regargs BOOL
MatchWindow(struct Window *win, UWORD Options, STRPTR Pattern)
{
BOOL result;
struct Task *WinTask;
STRPTR TaskName;
if (win)
{
if (Options & HKO_EXCLUDE_WB_DRAWERS)
{
result = !(win->Flags & WFLG_WBENCHWINDOW);
}
else
{
result = TRUE;
}
if ((result==TRUE) && !(Options & HKO_ACTIVATE_ONLY))
{
result = !(win->Flags & WFLG_BACKDROP);
}
if ((result==TRUE) && (Options & HKO_BY_WINDOW_TASK_NAME))
{
/* This is the task attached to our window */
if ((WinTask = win->UserPort->mp_SigTask) &&
(TaskName = WinTask->tc_Node.ln_Name))
{
/* Does its name match our pattern? */
result = MatchPattern(Pattern, TaskName);
}
else
{
result = FALSE;
}
}
}
else
{
result = FALSE;
}
return(result);
}
/* This function cycle through specified windows
* WARNING: it must be called under Forbid()/LockIBase()
*/
void
SelectiveCycleWindows(struct Screen *s,
UWORD Options,
STRPTR Pattern)
{
struct Layer *l;
struct Window *curwin = NULL;
struct Window *next;
struct Window *backmost = NULL;
if (l = s->LayerInfo.top_layer)
{
/* starting from top layer one, find backmost window
* that matches our criterias
*/
for (l = s->LayerInfo.top_layer; l; l = l->back)
{
curwin = (struct Window *)l->Window;
if (MatchWindow(curwin, Options, Pattern))
backmost = curwin;
}
l = backmost->WLayer;
if (Options & HKO_ACTIVATE_ONLY)
{
if ((IntuitionBase->ActiveWindow) &&
(IntuitionBase->ActiveWindow->WScreen == s))
{
curwin = IntuitionBase->ActiveWindow;
}
else
{
curwin = s->FirstWindow;
}
}
else
{
curwin = backmost;
}
if (curwin)
{
l = curwin->WLayer;
next = curwin;
if (Options & HKO_ACTIVATE_ONLY)
{
while (l &&
(!MatchWindow(next, Options, Pattern) ||
(next == curwin)))
{
next = (struct Window *)l->Window;
l = l->front;
}
if (next == curwin)
{
/* We have reached TopLayer window, so go back to back most one */
next = backmost;
}
}
else
{
while (l &&
!MatchWindow(next, Options, Pattern))
{
next = (struct Window *)l->Window;
l = l->front;
}
ScreenToFront(next->WScreen);
WindowToFront(next);
}
ActivateWindow(next);
}
}
}
/*
* This function cycle through specified windows but in the inverse
* direction as the one used by SelectiveCycleWindows().
* WARNING: it must be called under Forbid()/LockIBase()
*
*/
void
SelectiveBackCycleWindows(struct Screen *s,
UWORD Options,
STRPTR Pattern)
{
struct Layer *l;
struct Window *frontmost;
struct Window *previous;
struct Window *curwin = NULL;
if (l = s->LayerInfo.top_layer)
{
/* starting from top layer one, find frontmost window that matches
* our criterias.
*/
frontmost = NULL;
while (l && !MatchWindow(frontmost, Options, Pattern))
{
frontmost = (struct Window *)l->Window;
l = l->back;
}
if (frontmost)
{
if (Options & HKO_ACTIVATE_ONLY)
{
if ((IntuitionBase->ActiveWindow) &&
(IntuitionBase->ActiveWindow->WScreen == s))
{
curwin = IntuitionBase->ActiveWindow;
}
else
{
curwin = s->FirstWindow;
}
}
else
{
curwin = frontmost;
if (MatchWindow(curwin, Options, Pattern))
{
WindowToBack(curwin);
}
}
/* find the frontmost matching window by starting from the top layer
* We must take care to exclude the window we start from.
*/
l = curwin->WLayer;
previous = curwin;
while (l &&
(!MatchWindow(previous, Options, Pattern) ||
(previous == curwin)))
{
previous = (struct Window *)l->Window;
l = l->back;
}
if ((l == NULL) && ((previous == NULL) || (previous == curwin)))
{
/* We have reached the backmost window.*/
previous = frontmost;
}
if (!(Options & HKO_ACTIVATE_ONLY))
{
WindowToFront(previous);
}
ActivateWindow(previous);
}
}
}
void
act_CycleWindows(YakHotKey *yhk)
{
struct Screen *s;
PatternData pdata = {"",NULL};
ULONG lock;
if (s = SelectScreen(&yhk->yhk_Option[0]))
{
if (yhk->yhk_Option[1].Flags & HKO_BY_WINDOW_TASK_NAME)
{
InitPattern(yhk->yhk_Option[1].ArgStr[0], &pdata);
}
lock = LockIBase(0);
Forbid();
if (yhk->yhk_Option[1].Flags & HKO_BACK_CYCLE)
{
SelectiveBackCycleWindows(s, yhk->yhk_Option[1].Flags, pdata.pat);
}
else
{
SelectiveCycleWindows(s, yhk->yhk_Option[1].Flags, pdata.pat);
}
Permit();
UnlockIBase(lock);
}
}
/* taglist for CreateNewProc */
static LONG palette_taglist[] = {
NP_Entry, (LONG)DoPalette,
NP_Name, (LONG)"Yak Palette",
TAG_DONE
};
void
act_OpenPalette(YakHotKey *yhk)
{
ChangeScreen(&yhk->yhk_Option[0]);
CreateNewProc((struct TagItem *)palette_taglist);
}
void
act_ScreenToFront(YakHotKey *yhk)
{
struct Screen *s;
if (s=SelectScreen(&yhk->yhk_Option[0]))
{
MyScreenToFront(s);
}
}
void
act_ScreenToBack(YakHotKey *yhk)
{
struct Screen *s;
if (s=SelectScreen(&yhk->yhk_Option[0]))
{
MyScreenToBack(s);
}
}
void
act_ActivateWorkbench(YakHotKey *yhk)
{
struct Window *w;
if (w = FindWBWindow())
{
WBenchToFront();
ActivateWindow(w);
}
}
void
act_MoveScreen(YakHotKey *yhk)
{
struct Screen *scr;
if (scr = SelectScreen(&yhk->yhk_Option[0]))
{
YakMoveScreen(scr, yhk->yhk_Option[1].Flags);
}
}
void
act_BlankDisplay(YakHotKey *yhk)
{
BlankScreen();
}
void
act_InsertText(YakHotKey *yhk)
{
if (yhk->yhk_Option[0].ArgStr[0])
{
if (!AddToStream(yhk->yhk_Option[0].ArgStr[0], (UBYTE)yhk->yhk_Option[0].ArgNum[0]))
PostError("%s:\n \"%s\"",
getString(Text_insertion_str_invalid_ERR), yhk->yhk_Option[0].ArgStr[0]);
}
else PostError("%s \"%s\" %s",
getString(Yak_text_hotkey_ERR),
yhk->yhk_KeyDef,
getString(Has_no_text_specified_ERR));
}
void
act_InsertDate(YakHotKey *yhk)
{
struct DateTime dat;
DateStamp(&dat.dat_Stamp);
if (LocaleBase)
{
if (yhk->yhk_Option[0].ArgStr[0])
FormatDate(locale, yhk->yhk_Option[0].ArgStr[0], &dat.dat_Stamp, &putcharhook);
else PostError("%s \"%s\" %s",
getString(Yak_date_hotkey_ERR),
yhk->yhk_KeyDef,
getString(Has_no_format_specified_ERR));
}
else
{
/* pre-2.1 OS */
char datestr[LEN_DATSTRING];
dat.dat_Format = FORMAT_DOS;
dat.dat_Flags = 0;
dat.dat_StrDate = datestr;
dat.dat_StrDay = dat.dat_StrTime = NULL;
DateToStr(&dat);
AddToStream(datestr, 0);
}
}
void
act_ShowInterface(YakHotKey *yhk)
{
ChangeScreen(&yhk->yhk_Option[0]);
ShowYakInterface();
}
/* Set the active screen as default public screen if it a public screen
** else do nothing.
**/
void
act_CurrentScreenAsDefPub(YakHotKey *yhk)
{
UBYTE *PSName;
struct Screen *s;
/* Get the active screen */
s = ActiveScreen();
/* Get the name of our screen if it is a public screen */
PSName = GetPubScreenName(s);
if (PSName)
{
/* active screen is a public screen so
* make it default public screen
*/
SetDefaultPubScreen(PSName);
}
}
static void __regargs
YakMoveScreen(struct Screen *scr, UWORD flags)
{
struct Window *win;
struct Rectangle rect;
struct IBox b_box, f_box;
ULONG modeid;
WORD dx=0,dy=0;
if ( (modeid = GetVPModeID(&scr->ViewPort)) != INVALID_ID &&
QueryOverscan(modeid, &rect, OSCAN_TEXT))
{
if((flags & HKO_MOVE_VISIBLE_BAR) &&
(win=ActiveWindow()) &&
(win->WScreen == scr))
{
GetScreenBox(scr, &b_box, FALSE);
f_box.Left = win->LeftEdge;
f_box.Top = win->TopEdge;
f_box.Width = win->Width;
f_box.Height = win->Height;
}
else
{
b_box.Left = rect.MinX;
b_box.Top = rect.MinY;
b_box.Width = rect.MaxX - rect.MinX + 1;
b_box.Height = rect.MaxY - rect.MinY + 1;
f_box.Left = scr->LeftEdge;
f_box.Top = scr->TopEdge;
f_box.Width = scr->Width;
f_box.Height = scr->Height;
}
if (flags & HKO_MOVE_LEFT)
dx = b_box.Left - f_box.Left;
if (flags & HKO_MOVE_HORIZONTAL_CENTER)
dx = b_box.Left - f_box.Left + ((b_box.Width - f_box.Width) >> 1);
if (flags & HKO_MOVE_RIGHT)
dx = b_box.Left - f_box.Left + b_box.Width - f_box.Width;
if (flags & HKO_MOVE_TOP)
dy = b_box.Top - f_box.Top;
if (flags & HKO_MOVE_VERTICAL_CENTER)
dx = b_box.Top - f_box.Top + ((b_box.Height - f_box.Height) >> 1);
if (flags & HKO_MOVE_BOTTOM)
dy = b_box.Top - f_box.Top + b_box.Height - f_box.Height;
MoveScreen(scr, dx, dy);
}
}
static void __regargs
EnlargeWindow(struct Window *win, UWORD flags)
{
WORD width = win->Width,
height = win->Height,
top = win->TopEdge,
left = win->LeftEdge,
l;
struct IBox box;
struct Screen *s = win->WScreen;
GetScreenBox(s, &box, flags & HKO_RESIZE_VISIBLE_BAR);
if (flags & HKO_RESIZE_HORIZONTAL)
{
width = win->MaxWidth;
if (width == -1 || width > box.Width)
width = box.Width;
if (left < box.Left)
{
left = box.Left;
}
else
{
if ((l = box.Left + box.Width - left - width) < 0)
left += l;
}
}
if (flags & HKO_RESIZE_VERTICAL)
{
height = win->MaxHeight;
if (height == -1 || height > box.Height)
height = box.Height;
if (top < box.Top)
{
top = box.Top;
} else
{
if ((l = box.Top + box.Height - top - height) < 0)
top += l;
}
}
if (win->LeftEdge != left || win->TopEdge != top ||
win->Width != width || win->Height != height)
ChangeWindowBox(win,
left,
top,
width,
height);
}
static struct Window *
ActiveWindow(void)
{
ULONG lock;
struct Window *window=NULL;
lock = LockIBase(0);
window = IntuitionBase->ActiveWindow;
UnlockIBase(lock);
return window;
}
static struct Window *
WindowByTitle(STRPTR title)
{
struct Screen *screen = NULL;
struct Window *window = NULL;
BOOL WindowFound = FALSE;
PatternData pdata = {"",NULL};
if (InitPattern(title, &pdata))
{
ULONG lock = LockIBase(0);
screen = IntuitionBase->FirstScreen;
while (screen && !WindowFound)
{
window = screen->FirstWindow;
while (window && !WindowFound)
{
if (window->Title)
{
WindowFound = MatchPattern(pdata.pat, window->Title);
}
if (WindowFound == FALSE)
{
window = window->NextWindow;
}
}
screen = screen->NextScreen;
}
UnlockIBase(lock);
FreeVec(pdata.pat);
}
if (WindowFound)
{
return(window);
}
else
{
return(NULL);
}
}
static struct Screen *
ActiveScreen(void)
{
ULONG lock;
struct Screen *screen=NULL;
lock = LockIBase(0);
screen = IntuitionBase->ActiveScreen;
UnlockIBase(lock);
return (screen);
}
static struct Screen *
ScreenByTitle(STRPTR title)
{
struct Screen *screen = NULL;
PatternData pdata = {"",NULL};
BOOL ScreenFound = FALSE;
if (InitPattern(title, &pdata))
{
ULONG lock = LockIBase(0);
screen = IntuitionBase->FirstScreen;
while (screen && !ScreenFound)
{
if (screen->DefaultTitle)
{
ScreenFound=MatchPattern(pdata.pat, screen->DefaultTitle);
}
if (ScreenFound == FALSE)
{
screen = screen->NextScreen;
}
}
UnlockIBase(lock);
FreeVec(pdata.pat);
}
if (ScreenFound)
{
return(screen);
}
else
{
return(NULL);
}
}
struct Screen *
RearmostScreen(void)
{
ULONG lock;
struct Screen *screen=NULL, *ns;
lock = LockIBase(0);
screen = IntuitionBase->FirstScreen;
ns = screen->NextScreen;
while (ns)
{
screen = ns;
ns = screen->NextScreen;
}
UnlockIBase(lock);
return screen;
}
static struct Screen *
FrontmostScreen(void)
{
ULONG lock;
struct Screen *screen=NULL;
lock = LockIBase(0);
screen = IntuitionBase->FirstScreen;
UnlockIBase(lock);
return screen;
}
static struct Window *
SelectWindow(YakOption *opt)
{
struct Window *window=NULL;
switch (opt->Flags)
{
case HKO_ACTIVE:
window = ActiveWindow();
break;
case HKO_UNDER_MOUSE:
window = WindowUnderMouse();
break;
case HKO_BY_TITLE|HKO_PATTERN:
window = WindowByTitle(opt->ArgStr[0]);
break;
}
return window;
}
static struct Screen *
SelectScreen(YakOption *opt)
{
struct Screen *screen=NULL;
switch (opt->Flags)
{
case HKO_ACTIVE:
screen = ActiveScreen();
break;
case HKO_UNDER_MOUSE:
screen = ScreenUnderMouse();
break;
case HKO_BY_TITLE|HKO_PATTERN:
screen = ScreenByTitle(opt->ArgStr[0]);
break;
case HKO_REARMOST:
screen = RearmostScreen();
break;
case HKO_FRONTMOST:
screen = FrontmostScreen();
break;
}
return screen;
}
static void
ChangeScreen(YakOption *opt)
{
struct Screen *scr;
char *scrname;
if (!(opt->Flags & HKO_NO_SCREEN_CHANGE))
{
switch (opt->Flags)
{
case HKO_WORKBENCH_TO_FRONT:
scrname = "Workbench";
break;
case HKO_DEFAULT_PUBSCR_TO_FRONT:
scrname = NULL;
break;
}
if (scr = LockPubScreen(scrname))
{
ScreenToFront(scr);
UnlockPubScreen(NULL, scr);
}
}
}
/*
* the generic hotkey action stub
*/
void
PerformAction(YakHotKey *yhk)
{
/* and perform action (gobbledegook!? that's C for you...) */
(*(yhktypes[yhk->yhk_Type].yhkt_Command))(yhk);
}